package ua.kpi.flats.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import ua.kpi.flats.entity.BuyApplication;
import ua.kpi.flats.entity.Client;
import ua.kpi.flats.entity.Flat;
import ua.kpi.flats.entity.SaleApplication;
import ua.kpi.flats.entity.SuitableOption;
import ua.kpi.flats.service.ApplicationService;
import ua.kpi.flats.service.ClientService;

@Controller
public class ManagerController {
	private ApplicationService applicationService;
	private ClientService clientService;
	private Validator validator;
	
	public ManagerController() {
		ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
		validator = validatorFactory.getValidator();
	}
	
	@RequestMapping(value = "/manager/get_districts.do")
	public @ResponseBody Map<String,Object> getDistricts() {
		return applicationService.getDistricts();
	}

	@RequestMapping(value = "/manager/get_clients.do", method = RequestMethod.POST)
	public @ResponseBody Map<String,Object> getClients(@RequestParam("start") int from, 
													   @RequestParam("limit") int limit) {
		return clientService.getClients(from, limit);
	}
	
	@RequestMapping(value = "/manager/add_client.do", method = RequestMethod.POST)
	public @ResponseBody Map<String,Object> addClient(Client client) {
		Set<ConstraintViolation<Client>> violations = validator.validate(client);
		if (violations.size() > 0) {
			Map<String,Object> result = new HashMap<String,Object>();
			result.put("errors", true);
			return result;
		} else {
			return clientService.add(client);
		}		
	}
	
	@RequestMapping(value = "/manager/add_buy_application.do", method = RequestMethod.POST)
	public @ResponseBody Map<String,Object> addBuyApplication(BuyApplication app) {
		Set<ConstraintViolation<BuyApplication>> violations = validator.validate(app);
		Map<String,Object> response = new HashMap<String,Object>();
		if (violations.size() == 0) {			
			response.put("success", applicationService.addBuy(app));
		} else {
			response.put("invalidForm", true);
		}
		return response;
	}
	
	@RequestMapping(value = "/manager/add_sale_application.do", method = RequestMethod.POST)
	public @ResponseBody Map<String,Object> addSaleApplication(SaleApplication app) {
		Set<ConstraintViolation<Flat>> violations = validator.validate(app.getFlat());
		Set<ConstraintViolation<SaleApplication>> saleViols = validator.validate(app);
		Map<String,Object> response = new HashMap<String,Object>();
		if (violations.size() == 0 && saleViols.size() == 0) {
			response.put("success",applicationService.addSale(app));
		} else {
			response.put("invalidForm", true);
		}
		return response;
	}
	
	@RequestMapping(value = "/manager/get_buy_applications.do", method = RequestMethod.POST)
	public @ResponseBody Map<String,Object> getBuyApplications(@RequestParam("start") int from,
			                                                   @RequestParam("limit") int limit) {
		return applicationService.getBuyApplications(from, limit);
	}
	
	@RequestMapping(value = "/manager/get_sale_applications.do", method = RequestMethod.POST)
	public @ResponseBody Map<String,Object> getSaleApplications(@RequestParam("start") int from,
			                                                    @RequestParam("limit") int limit) {
		return applicationService.getSaleApplications(from, limit);
	}
	
	@RequestMapping(value = "/manager/get_buyapplication_details.do", method = RequestMethod.POST)
	public @ResponseBody BuyApplication getBuyApplicatoinDetails(@RequestParam("applicationId") long appId) {
		return applicationService.getBuyApp(appId);		
	}
	
	@RequestMapping(value = "/manager/get_saleapplication_details.do", method = RequestMethod.POST)
	public @ResponseBody SaleApplication getSaleApplicationDetails(@RequestParam("applicationId") long appId) {
		return applicationService.getSaleApp(appId);
	}
	
	@RequestMapping(value = "/manager/remove_buy_app.do", method = RequestMethod.POST)
	public @ResponseBody boolean removeBuyApplication(BuyApplication app) {
		return applicationService.removeBuyApp(app);
	}
	
	@RequestMapping(value = "/manager/remove_sale_app.do", method = RequestMethod.POST)
	public @ResponseBody boolean removeSaleApplication(SaleApplication app) {
		return applicationService.removeSaleApp(app);
	}
	
	@RequestMapping(value = "/manager/wainting_apps.do", method = RequestMethod.POST)
	public @ResponseBody Map<String,Object> waintingApps(@RequestParam("start") int from,
			                                             @RequestParam("limit") int limit) {
		return applicationService.waitingBuyApps(from, limit);
	}
	
	@RequestMapping(value = "/manager/get_suitable_options.do", method = RequestMethod.POST)
	public @ResponseBody List<SuitableOption> getSuitableOptions(@RequestParam("id") long id) {
		return applicationService.getOptions(id);
	}
	
	@Autowired
	public void setApplicationService(ApplicationService applicationService) {
		this.applicationService = applicationService;
	}
	
	@Autowired
	public void setClientService(ClientService clientService) {
		this.clientService = clientService;
	}
}
